<?

define('DB_COND_NOT_BETWEEN', -5);
define('DB_COND_NOT_IN', -4);
define('DB_COND_NOT_LIKE', -3);
define('DB_COND_LT', -2);
define('DB_COND_LTE', -1);
define('DB_COND_EQUAL', 0);
define('DB_COND_GTE', 1);
define('DB_COND_GT', 2);
define('DB_COND_LIKE', 3);
define('DB_COND_IN', 4);
define('DB_COND_BETWEEN', 5);
define('DB_COND_IS', 6);

define('DB_LOGIC_NOT', -1);
define('DB_LOGIC_AND', 0);
define('DB_LOGIC_OR', 1);

IncludeClass("SqlProcessor", __DIR__."/Database");

class Database {

    protected $px = "";
    protected $data = array();
    protected $action = false;

    public function __construct($params) {
        $this->px = !empty($params['prefix']) ? $params['prefix'] : "";
        return $this;
    }

    public function __call($name, $arguments) {
        Logger::error('Undefined method ' . __CLASS__ . "::" . $name);
        return $this;
    }

    public static final function Init($params = array()) {
        if (empty($params)) {
            $param_file = __DIR__ . "/Database/connect.ini";
            $params = parse_ini_file($param_file);
        }

        if (!empty($params['dbtype'])) {
            $classname = "\\Database\\" . $params['dbtype'];
            if (IncludeClass($classname, __DIR__ . "/Database")) {
                return new $classname($params);
            } else {
                return new Database($params);
            }
        } else {
            return new Database($params);
        }
    }

    function select() {
        $this->data['action'] = __FUNCTION__;
        return $this;
    }

    function insert() {
        $this->data['action'] = __FUNCTION__;
        return $this;
    }

    function update() {
        $this->data['action'] = __FUNCTION__;
        return $this;
    }


    function delete() {
        $this->data['action'] = __FUNCTION__;
        return $this;
    }

    function native($query) {
        $this->data['action'] = __FUNCTION__;
        $this->data['query'] = preg_replace("/@px:/", $this->px, $query);
        return $this;
    }

    function option($str) {
        $this->data[__FUNCTION__] = $str;
        return $this;
    }


    function table($tables, $alias = false) {
        if (is_array($tables)) {
            foreach ($tables as $table => $as) {
                if (is_numeric($table)) {
                    $table = $as;
                    $as = false;
                }
                $this->data[__FUNCTION__][] = array('table' => $this->px . $table, 'alias' => $as);
            }
        } else {
            $this->data[__FUNCTION__][] = array('table' => $this->px . $tables, 'alias' => $alias);
        }
        return $this;
    }

    function fields($tables = "*", $alias = false) {
        if (is_array($tables)) {
            foreach ($tables as $table => $as) {
                if (is_numeric($table)) {
                    $table = $as;
                    $as = false;
                }
                $this->data[__FUNCTION__][] = array('field' => $table, 'alias' => $as);
            }
        } else {
            $this->data[__FUNCTION__][] = array('field' => $tables, 'alias' => $alias);
        }
        return $this;
    }
    function order($field, $direction) {
        $this->data[__FUNCTION__][] = array(
            'field' => $field,
            'direction' => $direction,
        );
        return $this;
    }

    function limit($from, $length = false) {
        if(!$length){
            $length = $from;
            $from = 0;
        }
        $this->data[__FUNCTION__] = array(
            'from' => $from,
            'length' => $length,
        );
        return $this;
    }

    function values($values) {
        $data = func_get_args();
        foreach ($data as $value) {
            $this->data[__FUNCTION__][] = $value;
        }
        return $this;
    }

    function cond($filed, $value, $cond = DB_COND_EQUAL, $logic = DB_LOGIC_AND) {
        $this->data[__FUNCTION__][] = array(
            'field' => $filed,
            'value' => $value,
            'cond' => $cond,
            'logic' => $logic,
            'noquotes' => false,
        );
        $this->action = __FUNCTION__;
        return $this;
    }

    function set($filed, $value) {
        $this->data[__FUNCTION__][] = array(
            'field' => $filed,
            'value' => $value,
            'noquotes' => false,
        );
        $this->action = __FUNCTION__;
        return $this;
    }

  
    function noquotes() {
        $this->data[$this->action][count($this->data[$this->action]) - 1]['noquotes'] = true;
        return $this;
    }

    public function GetSql() {
        $str = "@action:";
        $data = $this->data;
        $SQLPROC = new SqlProcessor();
        foreach($data as $pattern=>$values){
            $str = preg_replace("#@$pattern:#", $SQLPROC->$pattern($values), $str);            
        }
        $str = preg_replace("#\s@[\w]+:#", "", $str);
        $SQLPROC = null;
        $this->data = array();
        return $str;
    }
}
